home *** CD-ROM | disk | FTP | other *** search
- _MULTIUSER DOS FOR CONTROL SYSTEMS: PART I_
- by Richard Kryszak
-
- [LISTING ONE]
-
- /* file name: system.c */
-
- #include <dos.h>
- #include "queues.h"
- #include <stdio.h>
-
- /*===============*/
- /* local defines */
- /*===============*/
- #define CCPM 0xE0 /* cdos call int value */
- #define C_DETACH 0x93 /* console detach CL register value */
- #define P_DELAY 0x8D /* process delay CL register value */
- #define P_DISPATCH 0x8E /* process dispatch CL register value */
- #define P_PRIOR 0x91 /* process priority CL register value */
- #define Q_CREAD 0x8A /* queue cread CL register value */
- #define Q_CWRITE 0x8C /* queue cwrite CL register value */
- #define Q_MAKE 0x86 /* queue make CL register value */
- #define Q_OPEN 0x87 /* queue open CL register value */
- #define Q_READ 0x89 /* queue read CL register value */
- #define Q_WRITE 0x8B /* queue write CL register value */
- #define S_MEMORY 0x59 /* system memory allocation request */
-
- /*=====================*/
- /* function prototypes */
- /*=====================*/
- unsigned int c_detach(void);
- void p_dispatch(void);
- void p_priority(unsigned char data);
- void p_delay(unsigned int del);
- unsigned int far * s_memory(int mem_size);
- int q_make(struct q_descriptor *descript_ptr,
- unsigned int msg_length,
- unsigned int num_msg,
- char que_name[8],
- int *err_ptr);
- int q_open(struct q_parameter_blk *param_blk_ptr,
- char que_name[8],
- int *err_ptr);
- int q_read(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
- int q_write(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
- int q_cread(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
- int q_cwrite(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
-
- /*======================*/
- /* function definitions */
- /*======================*/
- unsigned int c_detach()
- { union REGS inregs,outregs;
-
- inregs.h.cl = C_DETACH; /* detach function call */
- int86(CCPM,&inregs,&outregs); /* call cdos */
- return(outregs.x.ax); /* return call status */
- }
- void p_dispatch()
- { union REGS inregs,outregs;
-
- inregs.h.cl = P_DISPATCH; /* dispatch function call */
- int86(CCPM,&inregs,&outregs); /* call cdos */
- }
- void p_priority(unsigned char priority)
- { union REGS inregs,outregs;
-
- inregs.h.cl = P_PRIOR; /* priority change call */
- inregs.h.dl = priority; /* desired priority */
- int86(CCPM,&inregs,&outregs); /* call cdos */
- }
- void p_delay(unsigned int del)
- { union REGS inregs,outregs;
- inregs.h.cl = P_DELAY; /* delay function call */
- inregs.x.dx = del; /* number of ticks */
- int86(CCPM,&inregs,&outregs); /* call cdos */
- }
- unsigned int far * s_memory(int mem_size)
- { union REGS inregs,outregs;
- struct SREGS seg_regs; /* segment registers */
- unsigned int _far *mem_ptr=NULL; /* pointer to memory block */
- mem_size *= 2; /* compute # of bytes */
- inregs.h.cl = S_MEMORY; /* system memory allocation */
- inregs.x.dx = mem_size; /* # of bytes requested */
- int86x(CCPM,&inregs,&outregs,&seg_regs); /* call cdos */
- if(outregs.x.ax == 0xFFFF) /* if not successful */
- { return(NULL); /* return a null pointer */
- }
- mem_ptr = (unsigned int far *)
- ((0x10000 * seg_regs.es)
- + outregs.x.ax); /* convert into a pointer */
- return(mem_ptr); /* return the pointer */
- }
- int q_make(struct q_descriptor *descript_ptr,
- unsigned int msg_length,
- unsigned int num_msg,
- char que_name[8],
- int *err_ptr)
- { int int86_error; /* return status */
- int i; /* index variable */
- union REGS inregs, outregs; /* processor registers */
- struct SREGS seg_regs; /* segment registers */
- segread(&seg_regs); /* read segment registers */
- descript_ptr->internal_1 = 0; /* must be 0 */
- descript_ptr->internal_2 = 0; /* must be 0 */
- descript_ptr->internal_3 = 0; /* must be 0 */
- descript_ptr->internal_4 = 0; /* must be 0 */
- descript_ptr->internal_5 = 0; /* must be 0 */
- descript_ptr->internal_6 = 0; /* must be 0 */
- descript_ptr->msglen = msg_length; /* add message length */
- descript_ptr->nmsgs = num_msg; /* add number of messages */
- descript_ptr->flags = 0; /* no flags used */
- for(i = 0; i < 8; ++i) /* copy queue name */
- { descript_ptr->name[i]=que_name[i];
- }
- descript_ptr->buffer = 0; /* buffer in system area */
- inregs.h.cl = Q_MAKE; /* queue make call */
- inregs.x.dx = FP_OFF(descript_ptr); /* put offset into dx */
- int86_error=int86x(CCPM,&inregs,
- &outregs,&seg_regs); /* call cdos */
- *err_ptr = outregs.x.cx; /* write error code */
- return(int86_error); /* int86 return status */
- }
- int q_open(struct q_parameter_blk *param_blk_ptr,
- char que_name[8],
- int *err_ptr)
- { int int86_error; /* return status */
- int i; /* index variable */
- union REGS inregs, outregs; /* processor registers */
- struct SREGS seg_regs; /* segment registers */
- segread(&seg_regs); /* read segment registers */
- param_blk_ptr->internal_1 = 0; /* must be 0 */
- param_blk_ptr->internal_2 = 0; /* must be 0 */
- for(i = 0; i < 8; ++i)
- { param_blk_ptr->name[i] = que_name[i]; /* copy queue name */
- }
- inregs.h.cl = Q_OPEN; /* q_open call */
- inregs.x.dx = FP_OFF(param_blk_ptr); /* put offset into dx */
- int86_error=int86x(CCPM,&inregs,
- &outregs,&seg_regs); /* call cdos */
- *err_ptr = outregs.x.cx; /* write error code */
- return(int86_error); /* int86 return status */
- }
- int q_write(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr)
- { int int86_error; /* return status */
- union REGS inregs, outregs; /* processor registers */
- struct SREGS seg_regs; /* segment registers */
- segread(&seg_regs); /* read segment registers */
- param_blk_ptr->buffer=FP_OFF(buff_ptr); /* pointer to the buffer */
- inregs.h.cl = Q_WRITE; /* q_write call */
- inregs.x.dx = FP_OFF(param_blk_ptr); /* put offset into dx */
- int86_error=int86x(CCPM,&inregs, &outregs,&seg_regs); /* call cdos */
- *err_ptr = outregs.x.cx; /* write error code */
- return(int86_error); /* int86 return status */
- }
- int q_read(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr)
- { unsigned int int86_error; /* return status */
- union REGS inregs, outregs; /* processor registers */
- struct SREGS seg_regs; /* segment registers */
- segread(&seg_regs); /* read segment registers */
- param_blk_ptr->buffer=FP_OFF(buff_ptr); /* pointer to the buffer */
- inregs.h.cl = Q_READ; /* q_read call */
- inregs.x.dx = FP_OFF(param_blk_ptr); /* put offset into dx */
- int86_error=int86x(CCPM,&inregs,&outregs,&seg_regs); /* int86 call */
- *err_ptr = outregs.x.cx; /* write error code */
- return(int86_error); /* int86 return status */
- }
- int q_cwrite(struct q_parameter_blk *param_blk_ptr,unsigned char *buff_ptr,
- int *err_ptr)
- { int int86_error; /* return status */
- union REGS inregs, outregs; /* processor registers */
- struct SREGS seg_regs; /* segment registers */
- segread(&seg_regs); /* read segment registers */
- param_blk_ptr->buffer=FP_OFF(buff_ptr); /* pointer to the buffer */
- inregs.h.cl = Q_CWRITE; /* q_write call */
- inregs.x.dx = FP_OFF(param_blk_ptr); /* put offset into dx */
- int86_error=int86x(CCPM,&inregs,&outregs,&seg_regs); /* call cdos */
- *err_ptr = outregs.x.cx; /* write error code */
- return(int86_error); /* int86 return status */
- }
- int q_cread(struct q_parameter_blk *param_blk_ptr,unsigned char *buff_ptr,
- int *err_ptr)
- { int int86_error; /* return status */
- union REGS inregs, outregs; /* processor registers */
- struct SREGS seg_regs; /* segment registers */
- segread(&seg_regs); /* read segment registers */
- param_blk_ptr->buffer=FP_OFF(buff_ptr); /* pointer to the buffer */
- inregs.h.cl = Q_CREAD; /* q_cread call */
- inregs.x.dx = FP_OFF(param_blk_ptr); /* put offset into dx */
- int86_error=int86x(CCPM,&inregs,&outregs,&seg_regs); /* call cdos */
- *err_ptr = outregs.x.cx; /* write error */
- return(int86_error); /* int86 return status */
- }
-
-
-
- [LISTING TWO]
-
- /* file name: queues.h */
-
- struct q_descriptor
- { unsigned int internal_1; /* for internal use ; must be zero */
- unsigned int internal_2; /* for internal use ; must be zero */
- int flags; /* for internal use ; queue flags */
- char name[8]; /* queue name */
- int msglen; /* number of bytes in each logical message */
- int nmsgs; /* maximum number of messages supported */
- unsigned int internal_3; /* for internal use ; must be zero */
- unsigned int internal_4; /* for internal use ; must be zero */
- unsigned int internal_5; /* for internal use ; must be zero */
- unsigned int internal_6; /* for internal use ; must be zero */
- unsigned int buffer; /* address of the queue buffer */
- };
-
- struct q_parameter_blk
- { unsigned int internal_1; /* for internal use ; must be zero */
- int queueid; /* queue number field ; filled by q_open */
- unsigned int internal_2; /* for internal use ; must be zero */
- unsigned int buffer; /* offset of queue message buffer */
- char name[8]; /* queue name */
- };
-
-
-
-
- [LISTING THREE]
-
- /* file name: database.c */
-
- #include <stdio.h>
- #include "queues.h"
-
- /*=====================*/
- /* function prototypes */
- /*=====================*/
- void main(void);
-
- /*===============*/
- /* local defines */
- /*===============*/
- #define Q_DEPTH 1 /* queue contains 1 message */
- #define DBASE_SIZE 2048 /* size of the database */
- #define TRUE 1
-
- /*================================*/
- /* external function declarations */
- /*================================*/
- extern unsigned int c_detach(void);
- extern void p_delay(unsigned int del);
- extern unsigned int far *s_memory(int mem_size);
- extern int q_make(struct q_descriptor *descript_ptr,
- unsigned int msg_length,
- unsigned int num_msg,
- char que_name[8],
- int *err_ptr);
- extern int q_open(struct q_parameter_blk *param_blk_ptr,
- char que_name[8],
- int *err_ptr);
- extern int q_write(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
- /*=====================*/
- /* function definition */
- /*=====================*/
- void main()
- { int result; /* result of q_make */
- int error_type; /* cdos return code */
- union base
- { unsigned int far *base_ptr;
- unsigned char base[sizeof(unsigned int far *)];
- }base_union; /* composite pointer */
- struct q_descriptor dbase_descript; /* descriptor block */
- struct q_parameter_blk dbase_parameters; /* parameter block */
- base_union.base_ptr = s_memory(DBASE_SIZE); /* request system memory */
- if(base_union.base_ptr == NULL) /* if NULL pointer */
- { puts("No System Memory Available"); /* print an error message */
- exit(-1); /* exit, memory error */
- }
- result = q_make(&dbase_descript, /* pointer to descriptor */
- sizeof(base_union), /* length of messages */
- Q_DEPTH, /* number of messages */
- "database", /* queue name */
- &error_type); /* error return */
- result = q_open(&dbase_parameters, /* pointer to parameter */
- "database", /* queue name */
- &error_type); /* error return */
- result = q_cwrite(&dbase_parameters, /* write to queue */
- &base_union.base[0], /* pointer to database */
- &error_type); /* error return */
- c_detach(); /* detach from console */
- while(TRUE) /* loop */
- { p_delay(1800); /* delay 30 seconds */
- }
- }
- /* NOTE: DATABASE.EXE is made up of database.c and system.c */
-
-
-
- [LISTING FOUR]
-
- /* file name: dbsuport.c */
-
- #include <stdio.h>
- #include "queues.h"
-
- /*=====================*/
- /* function prototypes */
- /*=====================*/
- void dbopen(void);
- unsigned int dbread(int index);
- void dbwrit(int index, unsigned int value);
- unsigned int far *open_dbase(void);
-
- /*==============================*/
- /* external function prototypes */
- /*==============================*/
- extern int q_open(struct q_parameter_blk *param_blk_ptr,
- char que_name[8],
- int *err_ptr);
- extern void p_dispatch(void);
- extern int q_read(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
- extern int q_write(struct q_parameter_blk *param_blk_ptr,
- unsigned char *buff_ptr,
- int *err_ptr);
-
- /*================*/
- /* global storage */
- /*================*/
- unsigned int far *dbase_ptr; /* pointer to database */
-
- /*===============*/
- /* local defines */
- /*===============*/
- #define FAILURE 1
- #define SUCCESS 0
-
- /*======================*/
- /* function definitions */
- /*======================*/
- void dbopen()
- { dbase_ptr = NULL; /* initialize pointer */
- while(dbase_ptr == NULL) /* loop while still NULL */
- { dbase_ptr = open_dbase(); /* call open database */
- }
- }
- void dbwrit(int index, unsigned int value)
- { *(dbase_ptr + index) = value; /* write value to database */
- }
- unsigned int dbread(int index)
- { return(*(dbase_ptr + index)); /* return value at index */
- }
- unsigned int far *open_dbase()
- { struct q_parameter_blk dbase_parameters; /* parameter block */
- int result; /* result of q_make */
- int error_type; /* cdos return code */
- union base
- { unsigned int far *base_ptr;
- unsigned char base[sizeof(unsigned int far *)];
- }base_union; /* composite pointer */
- result = FAILURE; /* preset the variable */
- while(result != SUCCESS) /* loop til we can open */
- { result = q_open(&dbase_parameters, /* pointer to param block */
- "database", /* queue name */
- &error_type); /* error type return */
- p_dispatch(); /* let someone else run */
- }
- result = q_read(&dbase_parameters, /* read the dbase_queue */
- &base_union.base[0], /* msg read is in union */
- &error_type); /* error return type */
- result = q_write(&dbase_parameters, /* write to dbase_queue */
- &base_union.base[0], /* msg sent is pointer */
- &error_type); /* error return type */
- return(base_union.base_ptr); /* return the pointer */
- }
-
-
-
-
- [LISTING FIVE]
-
- /* file name ioboard.c */
-
- #include <conio.h>
-
- /*====================*/
- /* function prototype */
- /*====================*/
- void main(void);
-
- /*==============================*/
- /* external function prototypes */
- /*==============================*/
- extern void dbopen(void);
- extern void dbwrit(int index, unsigned int value);
- extern unsigned int dbread(int index);
- extern unsigned int c_detach(void);
- extern void p_priority(unsigned char data);
- extern void p_delay(unsigned int del);
-
- /*===============*/
- /* local defines */
- /*===============*/
- #define INPUT_BASE_ADDR 0x300 /* hardware input address */
- #define OUTPUT_BASE_ADDR 0x300 /* hardware output address */
- #define DBASE_WRITE_ADDR 0 /* database write location */
- #define DBASE_READ_ADDR 1 /* database read location */
- #define TRUE 1
-
- /*=====================*/
- /* function definition */
- /*=====================*/
- void main()
- { unsigned int temp_data; /* for reading database */
- p_priority(199); /* set priority */
- dbopen(); /* link to database */
- c_detach(); /* detach from console */
- while(TRUE)
- { temp_data = inp(INPUT_BASE_ADDR); /* read data from port */
- dbwrit(DBASE_WRITE_ADDR, temp_data); /* write to the database */
- temp_data = dbread(DBASE_READ_ADDR); /* read data from database */
- outp(OUTPUT_BASE_ADDR+3, temp_data); /* write to output port */
- p_delay(3); /* delay for 50 ms */
- }
- }
-
- /* NOTE: IOBOARD.EXE is made up of ioboard.c, system.c, and dbsuport.c */
-
-
-
- [LISTING SIX]
-
- /* file name logic.c */
-
- /*====================*/
- /* function prototype */
- /*====================*/
- void main(void);
-
- /*==============================*/
- /* external function prototypes */
- /*==============================*/
- extern void dbopen(void);
- extern unsigned int dbread(int index);
- extern void dbwrit(int index, unsigned int value);
- extern unsigned int c_detach(void);
- extern void p_dispatch(void);
-
- /*===============*/
- /* local defines */
- /*===============*/
- #define DATA_IN 0 /* data written by I/O process */
- #define DATA_OUT 1 /* data read by I/O process */
- #define TRUE 1
-
- /*=====================*/
- /* function definition */
- /*=====================*/
- void main()
- { static unsigned int last_data_read; /* old data retainer */
- unsigned int temp_data; /* for reading database */
-
- dbopen(); /* link to database */
- c_detach(); /* detach from console */
- while(TRUE) /* continuous loop */
- { temp_data = dbread(DATA_IN); /* read input data */
- if(temp_data ^ last_data_read) /* if there was a change */
- { dbwrit(DATA_OUT, ~temp_data); /* write the to the port */
- last_data_read = temp_data; /* save the new value */
- }
- p_dispatch(); /* let another process run */
- }
- }
- /* NOTE: LOGIC.EXE is made up of logic.c, system.c, and dbsuport.c */
-
-
-